package com.hmjk.health.background.data;

import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Intent;
import android.text.format.Time;
import android.util.Log;

import com.hmjk.health.HealthApp;
import com.hmjk.health.background.DataManager;
import com.hmjk.health.background.NetService;
import com.hmjk.health.background.data.DataUpdated;
import com.hmjk.health.util.DEV_DATA;
import com.hmjk.health.util.GlycoseReferenceSet;

public class GlycoseSetUpdated extends DataUpdated{
	private static String TAG = GlycoseSetUpdated.class.getSimpleName();
	private ArrayList<String> mTIDArray = new ArrayList<String>();
	private int index = 0;
	private boolean working = false;	
	private boolean doSingle = false;
	private static HashMap<String,GlycoseReferenceSet> mMap = new HashMap<String,GlycoseReferenceSet>();
	
	private void logd(String info){
		Log.d(TAG, info);
	}
	
	public GlycoseSetUpdated(HealthApp app, DataManager dm, DataUpdated base) {
		super(app, dm, base);
		UPDATE_TIME = 2 * 60 * 60 * 1000;
		mBaseData.setNotifer(DataManager.F_GLYCOSE_SET, this);
	}

	@Override
	public void setUserData(Object data) {
		// TODO Auto-generated method stub
		logd("setUserData");
		reqTime = 0;
		upTime = 0;
	}

	@Override
	public long delay() {
		
		long curMs = System.currentTimeMillis();
		long del = curMs - upTime;
		logd("delay curMs="+curMs+" upTime="+upTime+" del="+del);
		if(del >= UPDATE_TIME){
			logd("delay 0");
			return 0;
		}else{
			logd("delay (UPDATE_TIME - del) = "+(UPDATE_TIME - del));
			return (UPDATE_TIME - del);
		}
		
	}
	
	private void getTids(){
		JSONObject json = (JSONObject) mBaseData.check(null);
	
		mTIDArray.clear();
		index = 0;
		if(json != null){
			try {
				JSONArray ar = json.getJSONArray("array");
				int len = ar.length();
				for(int i = 0; i < len; i++){
					JSONObject e = ar.getJSONObject(i);
					String tid = e.getString("tid");
					String type = e.getString("type");
					logd("device, tid=" + tid + ", type=" + type);
					
					if(type.contains(DEV_DATA.TYPE_GLUCOSE_METER)){
						mTIDArray.add(tid);
					}
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	
	}
	
	private void doNextRequest(){
		if(doSingle){
			doSingle = false;
			working = false;
			return;
		}
		
		int size = mTIDArray.size();
		if(size > 0){
			index ++;
			if(index < size){
				doRequest();
			}else {
				working = false;
			}
		}else {
			working = false;
		}
	}
	
	private void doRequest(){	
		if(mTIDArray.size() == 0){
			logd("doRequest mTIDArray is empty");
			working = false;
			return;
		}
		
		logd("doRequest");
		
		String tid = mTIDArray.get(index);
		
		GlycoseReferenceSet set = mMap.get(tid);
		if(set == null){
			set = new GlycoseReferenceSet(tid);
			mMap.put(tid, set);
		}
		
		set.updatetime = System.currentTimeMillis();
		
		Intent si = new Intent(NetService.GET_DATA_ACTION);
		si.putExtra("sub_act", NetService.GET_GLYCOSE_SET);
		si.putExtra("uid", mApp.getUID());
		si.putExtra("tid", tid);
		
		Time t = new Time();
		t.setToNow();
		String stamp = "GET_GLYCOSE_SET" + t.toString(); 
		si.putExtra("stamp",stamp);
		mApp.addNetHandler(stamp,mDm.getBackGroundHandler());
		mApp.startService(si);
	}
	
	private void doSingleRequest(String tid){
		doSingle = true;
		GlycoseReferenceSet set = mMap.get(tid);
		if(set == null){
			set = new GlycoseReferenceSet(tid);
			mMap.put(tid, set);
		}
		set.updatetime = System.currentTimeMillis();
		
		Intent si = new Intent(NetService.GET_DATA_ACTION);
		si.putExtra("sub_act", NetService.GET_GLYCOSE_SET);
		si.putExtra("uid", mApp.getUID());
		si.putExtra("tid", tid);
		
		Time t = new Time();
		t.setToNow();
		String stamp = "GET_GLYCOSE_SET" + t.toString(); 
		si.putExtra("stamp",stamp);
		working = true;
		mApp.addNetHandler(stamp,mDm.getBackGroundHandler());
		mApp.startService(si);
	}

	@Override
	public boolean grab() {
		logd("grab");
	
		if(working){
			logd("grab working now");
			return false;
		}
		
		getTids();
		if (mTIDArray.isEmpty()) {
			logd("grab mTIDArray is empty");
			return false;
		}
				
		long curMs = System.currentTimeMillis();
		logd("grab curMs="+curMs+" reqTime="+reqTime);
		if((curMs - reqTime) > UPDATE_TIME){
			working = true;
			doRequest();
			reqTime = curMs;
			logd("grab req sent!");
			return true;
		}
		
		return false;
	}

	@Override
	public boolean grabByUser() {
		/*logd("grabByUser");
		
		if(working){
			logd("grabByUser working now");
			return false;
		}
				
		long curMs = System.currentTimeMillis();
		logd("grabByUser curMs="+curMs+" reqTime="+reqTime);
		if((curMs - reqTime) > MIN_QUERY_DUR * 1000){
			//doRequest(uid, argString);
			reqTime = curMs;
			logd("grabByUser req sent!");
			return true;
		}
		*/
		return false;
	}
	
	@Override
	public boolean grabByUserWithSingleArgs(Object args){
		if(args == null)
			return false;
		
		String[] argsArrays = (String[])args;
		if((argsArrays.length == 0) || (argsArrays[0] == null) || argsArrays[0].trim().isEmpty()){
			return false;
		}
		
		if(working){
			logd("grabByUserWithSingleArgs working");
			return false;
		}
		
		String tid = argsArrays[0];
	
		logd("grabByUserWithSingleArgs tid=" + tid);
		GlycoseReferenceSet d = mMap.get(tid);
		if(d == null){
			d = new GlycoseReferenceSet(tid);
			mMap.put(tid, d);
		}
		
		long curMs = System.currentTimeMillis();
		
		if((curMs - d.updatetime) > MIN_QUERY_DUR * 1000){
			working = true;
			doSingleRequest(tid);
			logd("grabByUserWithSingleArgs req sent!");
			return true;
		}else {
			logd("grabByUserWithSingleArgs wait for " + MIN_QUERY_DUR + "s");
			return false;
		}
		
	}	
	

	@Override
	public void receive(String stamp, String sjson) {
		if(stamp.startsWith("GET_GLYCOSE_SET")){
			if(sjson != null){
				boolean update = false;
				String tid = "";
				try {
					JSONObject json = new JSONObject(sjson);
					JSONObject senddata = json.getJSONObject("senddata");
					tid = senddata.getString("tid");
					int code = json.getInt("code");

					if(code == 200){
						String state = json.getString("state");
						if(state.equalsIgnoreCase("00")){
							JSONObject recdata = json.getJSONObject("recdata");
							
						    
							if(recdata != null){
								GlycoseReferenceSet set = mMap.get(tid);
								if(set == null){
									set = new GlycoseReferenceSet(tid);
									mMap.put(tid, set);
								}
								
								upTime = System.currentTimeMillis();
								set.updatetime = upTime;
								
								String unitString = recdata.getString("unit");
								if(unitString.isEmpty() || unitString.equalsIgnoreCase("NULL")){
									set.unit = 0;
								}else {
									set.unit = Integer.parseInt(unitString);
								}
								
								String voiceString = recdata.getString("voice");
								if(voiceString.isEmpty() || voiceString.equalsIgnoreCase("NULL")){
									set.voice = 1;
								}else {
									set.voice = Integer.parseInt(voiceString);
								}
						        
						        String glyS = recdata.getString("glycosylated");
						        
						        if(glyS.isEmpty() || glyS.equalsIgnoreCase("NULL")){
						        	set.glycosylated = GlycoseReferenceSet.DEFAULT_GLYCOSYLATED;
						        }else{
						        	set.glycosylated = Float.parseFloat(glyS);
						        }
						        
						        String blS = recdata.getString("beforelow");
						        if(blS.isEmpty() || blS.equalsIgnoreCase("NULL")){
						        	set.beforelow = GlycoseReferenceSet.DEFAULT_LOW;
						        }else{
						        	set.beforelow = Float.parseFloat(blS);
						        }
						        
						        String buS = recdata.getString("beforeupper");
						        if(buS.isEmpty() || buS.equalsIgnoreCase("NULL")){
						        	set.beforeupper = GlycoseReferenceSet.DEFAULT_HIGH;
						        }else{
						        	set.beforeupper = Float.parseFloat(buS);
						        }
						        
						        String alS = recdata.getString("afterlow");
						        if(alS.isEmpty() || alS.equalsIgnoreCase("NULL")){
						        	set.afterlow = GlycoseReferenceSet.DEFAULT_LOW;
						        }else{
						        	set.afterlow = Float.parseFloat(alS);
						        }
						       
						        String auS = recdata.getString("afterupper");
						        if(auS.isEmpty() || auS.equalsIgnoreCase("NULL")){
						        	set.afterupper = GlycoseReferenceSet.DEFAULT_HIGH;
						        }else{
						        	set.afterupper = Float.parseFloat(auS);
						        }
						        
						        String bedlS = recdata.getString("bedtimelow");
						        if(bedlS.isEmpty() || bedlS.equalsIgnoreCase("NULL")){
						        	set.bedtimelow = GlycoseReferenceSet.DEFAULT_LOW;
						        }else{
						        	set.bedtimelow = Float.parseFloat(bedlS);
						        }
						       
						        String beduS = recdata.getString("bedtimeupper");
						        if(beduS.isEmpty() || beduS.equalsIgnoreCase("NULL")){
						        	set.bedtimeupper = GlycoseReferenceSet.DEFAULT_HIGH;
						        }else{
						        	set.bedtimeupper = Float.parseFloat(beduS);
						        }
						        				        
						        String dlS = recdata.getString("dawnlow");
						        if(dlS.isEmpty() || dlS.equalsIgnoreCase("NULL")){
						        	set.dawnlow = GlycoseReferenceSet.DEFAULT_LOW;
						        }else{
						        	set.dawnlow = Float.parseFloat(dlS);
						        }
						       
						        String duS = recdata.getString("dawnupper");
						        if(duS.isEmpty() || duS.equalsIgnoreCase("NULL")){
						        	set.dawnupper = GlycoseReferenceSet.DEFAULT_HIGH;
						        }else{
						        	set.dawnupper = Float.parseFloat(duS);
						        }
								update = true;
								}
							}
						}
				}catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				doNextRequest();
				Intent i = new Intent(DataManager.DATA_UPDATE_ACTION);
				i.putExtra("type",DataManager.F_GLYCOSE_SET);
				i.putExtra("tid", tid);
				i.putExtra("state", update);
				mApp.sendBroadcast(i);
			}
		}else if(stamp.startsWith("COMMIT_GLYCOSE_SET")){
			if(sjson != null){
				String state = "af";
				String tid = "";
				int code = 400;
				try {
					JSONObject json = new JSONObject(sjson);
					code = json.getInt("code");
					JSONObject sd = json.getJSONObject("senddata");
					tid = sd.getString("tid");
					
					if(code == 200){
						state = json.getString("state");
						if(state.equalsIgnoreCase("00")){						
							GlycoseReferenceSet set = mMap.get(tid);
							if(set == null){
								set = new GlycoseReferenceSet(tid);
								mMap.put(tid, set);
							}

							set.updatetime = System.currentTimeMillis();
							
					        set.unit = Integer.parseInt(sd.getString("unit"));
					        
					        set.voice = Integer.parseInt(sd.getString("voice"));
					        
					        String glyS = sd.getString("glycosylated");
					        set.glycosylated = Float.parseFloat(glyS);
					        
					        String blS = sd.getString("beforelow");
					        set.beforelow = Float.parseFloat(blS);;	
					        
					        String buS = sd.getString("beforeupper");
					        set.beforeupper = Float.parseFloat(buS);	
					        
					        String alS = sd.getString("afterlow");
					        set.afterlow = Float.parseFloat(alS);
					        
					        String auS = sd.getString("afterupper");
					        set.afterupper = Float.parseFloat(auS);
					        
					        String bedlS = sd.getString("bedtimelow");
					        set.bedtimelow = Float.parseFloat(bedlS);	
					        
					        String beduS = sd.getString("bedtimeupper");
					        set.bedtimeupper = Float.parseFloat(beduS);	
					        
					        String dlS = sd.getString("dawnlow");
					        set.dawnlow = Float.parseFloat(dlS);
					        
					        String duS = sd.getString("dawnupper");
					        set.dawnupper = Float.parseFloat(duS);
						}
					}
				}catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					state = "af";
				}
				Intent i = new Intent(DataManager.DATA_COMMIT_RESULT);
				i.putExtra("type",DataManager.F_GLYCOSE_SET);
				i.putExtra("tid", tid);
				i.putExtra("state", state);
				i.putExtra("code", code);
				mApp.sendBroadcast(i);
			}
		}
		
	}
	
	@Override
	public Object check(String[] arg) {
		if((arg != null) && (arg.length > 0)){
			
			String tid = arg[0];
			
			GlycoseReferenceSet set = mMap.get(tid);
			if(set == null){
				set = new GlycoseReferenceSet(tid);
				mMap.put(tid, set);
			}
			return set;
		}
		return null;
	}

	@Override
	public boolean commit(Object data) {
		GlycoseReferenceSet set = (GlycoseReferenceSet)data;
		
		Intent si = new Intent(NetService.COMMIT_DATA_ACTION);
		si.putExtra("sub_act", NetService.COMMIT_GLYCOSE_SET);
		
		
		si.putExtra("uid", mApp.getUID());
        si.putExtra("tid", set.tid);
        
        si.putExtra("unit", Integer.toString(set.unit));
        si.putExtra("voice", Integer.toString(set.voice));
        si.putExtra("glycosylated", Float.toString(set.glycosylated));
        si.putExtra("beforelow", Float.toString(set.beforelow));
        si.putExtra("beforeupper", Float.toString(set.beforeupper));
        si.putExtra("afterlow", Float.toString(set.afterlow));
        si.putExtra("afterupper", Float.toString(set.afterupper));
        si.putExtra("bedtimelow", Float.toString(set.bedtimelow));
        si.putExtra("bedtimeupper", Float.toString(set.bedtimeupper));
        si.putExtra("dawnlow", Float.toString(set.dawnlow));
        si.putExtra("dawnupper", Float.toString(set.dawnupper));
        
		Time t = new Time();
		t.setToNow();
		String stamp = "COMMIT_GLYCOSE_SET" + t.toString(); 
		si.putExtra("stamp",stamp);
		mApp.addNetHandler(stamp,mDm.getBackGroundHandler());
		mApp.startService(si);
		return true;
	}

	@Override
	public void release() {
		// TODO Auto-generated method stub
		
	}
}
